frame-clock: Add 'compute-size' phase
authorJonas Ådahl <jadahl@gmail.com>
Tue, 24 Nov 2020 14:02:35 +0000 (15:02 +0100)
committerJonas Ådahl <jadahl@gmail.com>
Mon, 7 Dec 2020 08:46:39 +0000 (09:46 +0100)
This will be handled between 'update' (which may trigger animation
ticks, CSS update, etc) and 'layout' which will allocate the widget
tree. It's meant to perform surface size computation, and is done
between these two phases in order to have an up to date state, and
letting the layout phase have an up to date size to layout in.

gdk/gdkframeclock.c
gdk/gdkframeclock.h
gdk/gdkframeclockidle.c
gdk/gdkframeclockprivate.h

index 5e4492744c4f44b7776aa7aa344669ab7e9c8525..15efa30afefc31f46d23b0fca4bca5a37f323aef 100644 (file)
@@ -78,6 +78,7 @@ enum {
   FLUSH_EVENTS,
   BEFORE_PAINT,
   UPDATE,
+  COMPUTE_SIZE,
   LAYOUT,
   PAINT,
   AFTER_PAINT,
@@ -184,6 +185,21 @@ gdk_frame_clock_class_init (GdkFrameClockClass *klass)
                   NULL, NULL, NULL,
                   G_TYPE_NONE, 0);
 
+  /**
+   * GdkFrameClock::compute-size:
+   * @clock: the frame clock emitting the signal
+   *
+   * This signal is used for computing the size of the underlying
+   * #GdkSurface. Applications should generally not handle this signal.
+   */
+  signals[COMPUTE_SIZE] =
+    g_signal_new (g_intern_static_string ("compute-size"),
+                  GDK_TYPE_FRAME_CLOCK,
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL, NULL, NULL,
+                  G_TYPE_NONE, 0);
+
   /**
    * GdkFrameClock::layout:
    * @clock: the frame clock emitting the signal
@@ -682,6 +698,18 @@ _gdk_frame_clock_emit_update (GdkFrameClock *frame_clock)
   gdk_profiler_end_mark (before, "frameclock update", NULL);
 }
 
+void
+_gdk_frame_clock_emit_compute_size (GdkFrameClock *frame_clock)
+{
+  gint64 before G_GNUC_UNUSED;
+
+  before = GDK_PROFILER_CURRENT_TIME;
+
+  g_signal_emit (frame_clock, signals[COMPUTE_SIZE], 0);
+
+  gdk_profiler_end_mark (before, "frameclock compute size", NULL);
+}
+
 void
 _gdk_frame_clock_emit_layout (GdkFrameClock *frame_clock)
 {
index a2eba246ad92c4c3684f87b3a6fe1f753114cbe4..dfe0c23747f7cacb8f62f251abff03ce0e783bd7 100644 (file)
@@ -50,6 +50,7 @@ typedef struct _GdkFrameClockClass         GdkFrameClockClass;
  * @GDK_FRAME_CLOCK_PHASE_FLUSH_EVENTS: corresponds to GdkFrameClock::flush-events. Should not be handled by applications.
  * @GDK_FRAME_CLOCK_PHASE_BEFORE_PAINT: corresponds to GdkFrameClock::before-paint. Should not be handled by applications.
  * @GDK_FRAME_CLOCK_PHASE_UPDATE: corresponds to GdkFrameClock::update.
+ * @GDK_FRAME_CLOCK_PHASE_COMPUTE_SIZE: corresponds to GdkFrameClock::compute-size. Should not be handled by applications.
  * @GDK_FRAME_CLOCK_PHASE_LAYOUT: corresponds to GdkFrameClock::layout.
  * @GDK_FRAME_CLOCK_PHASE_PAINT: corresponds to GdkFrameClock::paint.
  * @GDK_FRAME_CLOCK_PHASE_RESUME_EVENTS: corresponds to GdkFrameClock::resume-events. Should not be handled by applications.
@@ -64,10 +65,11 @@ typedef enum {
   GDK_FRAME_CLOCK_PHASE_FLUSH_EVENTS  = 1 << 0,
   GDK_FRAME_CLOCK_PHASE_BEFORE_PAINT  = 1 << 1,
   GDK_FRAME_CLOCK_PHASE_UPDATE        = 1 << 2,
-  GDK_FRAME_CLOCK_PHASE_LAYOUT        = 1 << 3,
-  GDK_FRAME_CLOCK_PHASE_PAINT         = 1 << 4,
-  GDK_FRAME_CLOCK_PHASE_RESUME_EVENTS = 1 << 5,
-  GDK_FRAME_CLOCK_PHASE_AFTER_PAINT   = 1 << 6
+  GDK_FRAME_CLOCK_PHASE_COMPUTE_SIZE  = 1 << 3,
+  GDK_FRAME_CLOCK_PHASE_LAYOUT        = 1 << 4,
+  GDK_FRAME_CLOCK_PHASE_PAINT         = 1 << 5,
+  GDK_FRAME_CLOCK_PHASE_RESUME_EVENTS = 1 << 6,
+  GDK_FRAME_CLOCK_PHASE_AFTER_PAINT   = 1 << 7
 } GdkFrameClockPhase;
 
 GDK_AVAILABLE_IN_ALL
index 4870a110a635bc914c87be692ec2b3e060cdac7a..ac69aba627410d787720441aef11d4686754f43b 100644 (file)
@@ -552,6 +552,18 @@ gdk_frame_clock_paint_idle (void *data)
             }
           G_GNUC_FALLTHROUGH;
 
+        case GDK_FRAME_CLOCK_PHASE_COMPUTE_SIZE:
+          if (priv->freeze_count == 0)
+            {
+              priv->phase = GDK_FRAME_CLOCK_PHASE_COMPUTE_SIZE;
+              if ((priv->requested & GDK_FRAME_CLOCK_PHASE_COMPUTE_SIZE) != 0)
+                {
+                  priv->requested &= ~GDK_FRAME_CLOCK_PHASE_COMPUTE_SIZE;
+                  _gdk_frame_clock_emit_compute_size (clock);
+                }
+            }
+          G_GNUC_FALLTHROUGH;
+
         case GDK_FRAME_CLOCK_PHASE_LAYOUT:
           if (priv->freeze_count == 0)
             {
index 010aa4564f015dc226dfaef67d84a9a962f5a1b4..a68bc85da89dd77513782fd17ddfba9335c188ba 100644 (file)
@@ -122,6 +122,7 @@ gboolean         _gdk_frame_timings_steal (GdkFrameTimings *timings,
 void _gdk_frame_clock_emit_flush_events  (GdkFrameClock *frame_clock);
 void _gdk_frame_clock_emit_before_paint  (GdkFrameClock *frame_clock);
 void _gdk_frame_clock_emit_update        (GdkFrameClock *frame_clock);
+void _gdk_frame_clock_emit_compute_size  (GdkFrameClock *frame_clock);
 void _gdk_frame_clock_emit_layout        (GdkFrameClock *frame_clock);
 void _gdk_frame_clock_emit_paint         (GdkFrameClock *frame_clock);
 void _gdk_frame_clock_emit_after_paint   (GdkFrameClock *frame_clock);